// user/User.java
package user;

public abstract class User {
    protected String name;
    protected int userID;
    protected String role;

    public User(String name, int userID, String role) {
        this.name = name;
        this.userID = userID;
        this.role = role;
    }

    public String getName() { return name; }
    public int getUserID() { return userID; }
    public String getRole() { return role; }

    public abstract int display();
}

// user/AdminUser.java
package user;

        import book.Library;
        import constant.Constant;
        import utils.LibrarySingleton;
        import utils.ScannerSingleton;
        import java.time.LocalDate;
        import java.util.Scanner;

public class AdminUser extends User {
    private Scanner scanner;
    private Library library;

    public AdminUser(String name, int userID) {
        super(name, userID, "管理员");
        this.library = LibrarySingleton.getInstance();
        this.scanner = ScannerSingleton.getInstance();
    }

    @Override
    public int display() {
        System.out.println("管理员 " + name + " 的操作菜单:");
        System.out.println("1. 查找图书");
        System.out.println("2. 打印所有的图书");
        System.out.println("3. 退出系统");
        System.out.println("4. 上架图书");
        System.out.println("5. 修改图书");
        System.out.println("6. 下架图书");
        System.out.println("7. 统计借阅次数");
        System.out.println("8. 查看最受欢迎的前K本书");
        System.out.println("9. 查看库存状态");
        System.out.println("10. 按类别统计图书");
        System.out.println("11. 按作者统计图书");
        System.out.println("12. 检查超过一年未下架的图书");
        System.out.println("请选择你的操作:");
        return scanner.nextInt();
    }

    public void addBook() {
        scanner.nextLine();
        System.out.println("请输入书名:");
        String title = scanner.nextLine();
        System.out.println("请输入作者:");
        String author = scanner.nextLine();
        System.out.println("请输入类别:");
        String category = scanner.nextLine();
        System.out.println("请输入出版年份:");
        int year = scanner.nextInt();
        scanner.nextLine();

        LocalDate shelfDate = LocalDate.now();
        book.Book newBook = new book.Book(title, author, category, year, shelfDate);
        library.addBook(newBook);
    }

    public void updateBook() {
        library.displayBooks();
        System.out.println("请输入要修改的图书id:");
        int bookId = scanner.nextInt();
        scanner.nextLine();

        book.Book book = library.searchById(bookId);
        if (book == null) {
            System.out.println("没有ID为:" + bookId + " 的书籍!");
            return;
        }

        System.out.println("当前书名:" + book.getTitle());
        System.out.println("请输入新的书名:");
        String newTitle = scanner.nextLine();
        System.out.println("当前作者:" + book.getAuthor());
        System.out.println("请输入新的作者:");
        String newAuthor = scanner.nextLine();
        System.out.println("当前类别:" + book.getCategory());
        System.out.println("请输入新的类别:");
        String newCategory = scanner.nextLine();

        book.setTitle(newTitle);
        book.setAuthor(newAuthor);
        book.setCategory(newCategory);
        library.updateBook(book);
    }

    public void removeBook() {
        library.displayBooks();
        System.out.println("请输入要删除的图书的ID:");
        int bookId = scanner.nextInt();
        scanner.nextLine();

        book.Book removeBook = library.searchById(bookId);
        if (removeBook != null) {
            library.removeBook(bookId);
            System.out.println("图书:" + removeBook.getTitle() + " 已经被删除!");
        }
    }

    public void borrowCount() {
        library.borrowCount();
    }

    public void generateBook() {
        System.out.println("请输入你要查看的最受欢迎的前K本书,注意k值不能超过:" + library.getBookCount());
        int k = scanner.nextInt();
        if (k <= 0 || k > library.getBookCount()) {
            System.out.println("没有最受欢迎的前" + k + "本书!");
            return;
        }
        library.generateBook(k);
    }

    public void checkInventoryStatus() {
        library.checkInventoryStatus();
    }

    public void categorizeBooksByCategory() {
        library.categorizeBooksByCategory();
    }

    public void categorizeBooksByAuthor() {
        library.categorizeBooksByAuthor();
    }

    public void checkAndRemoveOldBooks() {
        library.checkAndRemoveOldBooks(scanner);
    }

    public void exit() {
        library.exit();
    }
}

// user/NormalUser.java
package user;

        import book.Library;
        import book.PairOfUidAndBookId;
        import constant.Constant;
        import utils.AnalyzingBorrowedBook;
        import utils.LibrarySingleton;
        import utils.ScannerSingleton;
        import java.util.Scanner;

public class NormalUser extends User {
    private PairOfUidAndBookId[] pairOfUidAndBookIds;
    private int borrowedCount;
    private static final int BORROW_BOOK_MAX_NUM = 5;
    private final AnalyzingBorrowedBook analyzingBorrowedBook = new AnalyzingBorrowedBook();
    private Scanner scanner;
    private Library library;

    public NormalUser(String name, int userID) {
        super(name, userID, "普通用户");
        this.library = LibrarySingleton.getInstance();
        this.scanner = ScannerSingleton.getInstance();
        loadBorrowedBook();
    }

    @Override
    public int display() {
        System.out.println("普通用户 " + name + " 的操作菜单:");
        System.out.println("1. 查找图书");
        System.out.println("2. 打印所有的图书");
        System.out.println("3. 退出系统");
        System.out.println("4. 借阅图书");
        System.out.println("5. 归还图书");
        System.out.println("6. 查看当前个人借阅情况");
        System.out.println("请选择你的操作:");
        return scanner.nextInt();
    }

    public void borrowBook() {
        scanner.nextLine();
        System.out.println("请输入你要借阅图书的id:");
        int bookId = scanner.nextInt();
        scanner.nextLine();

        if (library.getBookCount() == 0) {
            System.out.println("书架没有书籍暂且不能借阅");
            return;
        }

        loadBorrowedBook();
        book.Book book = library.searchById(bookId);
        if (book == null) {
            System.out.println("没有该id的相关书籍:" + bookId);
            return;
        }

        for (int i = 0; i < borrowedCount; i++) {
            PairOfUidAndBookId pair = pairOfUidAndBookIds[i];
            if (pair.getBookId() == book.getBookId()) {
                if (getUserID() == pair.getUserId()) {
                    System.out.println("该书已经被你借阅过了,你的ID是:" + getUserID());
                    return;
                } else {
                    System.out.println("该书已经被其他人借阅过了,他的ID是:" + pair.getUserId());
                    return;
                }
            }
        }

        library.borrowBook(bookId);
        PairOfUidAndBookId newPair = new PairOfUidAndBookId(userID, book.getBookId());
        pairOfUidAndBookIds[borrowedCount] = newPair;
        borrowedCount++;
        storeBorrowedBook();
        System.out.println("借阅成功!");
    }

    public void returnBook() {
        loadBorrowedBook();
        if (borrowedCount == 0) {
            System.out.println("目前没有用户借阅过书籍");
            return;
        }

        scanner.nextLine();
        System.out.println("请输入你要归还图书的id:");
        int bookId = scanner.nextInt();
        scanner.nextLine();

        book.Book book = library.searchById(bookId);
        if (book == null) {
            System.out.println("没有该id的相关书籍:" + bookId);
            return;
        }

        for (int i = 0; i < borrowedCount; i++) {
            PairOfUidAndBookId pair = pairOfUidAndBookIds[i];
            if (pair.getBookId() == book.getBookId() && getUserID() == pair.getUserId()) {
                library.returnBook(bookId);
                System.out.println("图书 '" + book.getTitle() + "' 已成功归还｡");

                pairOfUidAndBookIds[i] = pairOfUidAndBookIds[borrowedCount - 1];
                pairOfUidAndBookIds[borrowedCount - 1] = null;
                borrowedCount--;
                storeBorrowedBook();
                return;
            }
        }
        System.out.println("你没有借阅该书籍,不需要归还,书籍ID为:" + bookId);
    }

    public void viewBorrowBooks() {
        loadBorrowedBook();
        System.out.println("您的借阅情况如下:");
        if (borrowedCount == 0) {
            System.out.println("目前没有借阅记录.....");
        } else {
            boolean hasRecord = false;
            for (int i = 0; i < borrowedCount; i++) {
                PairOfUidAndBookId pair = pairOfUidAndBookIds[i];
                if (pair.getUserId() == userID) {
                    hasRecord = true;
                    book.Book book = library.searchById(pair.getBookId());
                    System.out.println(book);
                }
            }
            if (!hasRecord) {
                System.out.println("你没有借阅过书籍!");
            }
        }
    }

    private void loadBorrowedBook() {
        try {
            PairOfUidAndBookId[] allBorrowed = analyzingBorrowedBook.loadObject(Constant.BORROWED_BOOK_FILE_NAME);
            pairOfUidAndBookIds = new PairOfUidAndBookId[BORROW_BOOK_MAX_NUM];
            if (allBorrowed == null) {
                borrowedCount = 0;
                return;
            }

            int len = allBorrowed.length;
            if (len > pairOfUidAndBookIds.length) {
                pairOfUidAndBookIds = new PairOfUidAndBookId[len];
            }
            for (int i = 0; i < len; i++) {
                pairOfUidAndBookIds[i] = allBorrowed[i];
            }
            borrowedCount = len;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void storeBorrowedBook() {
        try {
            analyzingBorrowedBook.storeObject(pairOfUidAndBookIds, Constant.BORROWED_BOOK_FILE_NAME);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}